static const uint8_t PROGMEM odoDigits[] = { // Odometer-style digits
  0x00,0x00,0x00,0x15,0x4A,0x15,0xB7,0x23,0xB7,0xC8,0x15,0xC8,0x6E,0x15,0x6E,
  0x0A,0x23,0x0A,0x00,0x00,0x00,0x4A,0xFF,0x4A,0x99,0x4A,0x99,0xFF,0x00,0xFF,
  0x6E,0x15,0x6E,0x2C,0x15,0x2C,0x00,0x00,0x00,0x00,0x4A,0x00,0xFF,0x00,0xFF,
  0xFF,0x00,0xFF,0xB7,0x23,0xB7,0x2C,0x15,0x2C,0x06,0x15,0x06,0x00,0x23,0x00,
  0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x00,0xFF,0x49,0x23,0x49,0x06,0x15,0x06,
  0x00,0x15,0x00,0x00,0x7B,0x00,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x99,0x4A,0x99,
  0x0A,0x23,0x0A,0x00,0x15,0x00,0x00,0x4A,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,
  0x4A,0xFF,0x4A,0x15,0x4A,0x15,0x00,0x00,0x00,0x00,0x4A,0x00,0x00,0x98,0x00,
  0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x23,0x00,
  0x00,0x98,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0x4A,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x7B,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0x7B,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4A,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,
  0x00,0x98,0x00,0x00,0x23,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,
  0x00,0xFF,0x00,0x00,0x98,0x00,0x00,0x4A,0x00,0x00,0x00,0x00,0x4A,0x4A,0x15,
  0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0x4A,0x00,0x00,0x15,0x00,
  0x23,0x23,0x0A,0x4A,0x4A,0x99,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0x7B,0x00,
  0x00,0x15,0x00,0x15,0x15,0x06,0x23,0x23,0x49,0x15,0x4A,0x99,0x00,0xFF,0x00,
  0x00,0xFF,0x00,0x00,0x23,0x00,0x15,0x15,0x06,0x15,0x15,0x2C,0x49,0x7B,0x7B,
  0x99,0x4A,0x15,0x00,0xFF,0x00,0x00,0x4A,0x00,0x00,0x00,0x00,0x15,0x15,0x2C,
  0x2C,0x4A,0x4A,0x49,0x23,0x49,0xFF,0x4A,0x4A,0x00,0x00,0x00,0x00,0x00,0x00,
  0x23,0x23,0x0A,0x2C,0x4A,0x4A,0x6E,0x4A,0x4A,0xB7,0x7B,0x49,0x4A,0x4A,0x4A,
  0x00,0x00,0x00,0x00,0x00,0x00,0x23,0x23,0x49,0x6E,0x4A,0x4A,0x6E,0x4A,0x6E,
  0x7B,0x23,0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x4A,0x4A,0x15,0x49,0x7B,0x7B,
  0x6E,0x4A,0x6E,0x6E,0x4A,0x2C,0x23,0x23,0x23,0x00,0x00,0x00,0xFF,0xFF,0x4A,
  0x4A,0x4A,0x99,0x49,0x23,0x49,0x6E,0x4A,0x2C,0x4A,0x15,0x15,0x00,0x00,0x00,
  0x4A,0x4A,0x15,0x00,0x00,0xFF,0x15,0x4A,0x99,0xB7,0x7B,0x49,0x4A,0x15,0x15,
  0x15,0x15,0x15,0x23,0x23,0x0A,0x4A,0x4A,0x99,0x4A,0xFF,0x4A,0x99,0x4A,0x15,
  0x7B,0x23,0x23,0x15,0x15,0x15,0x15,0x15,0x06,0x23,0x23,0x49,0x00,0x4A,0x99,
  0xFF,0x00,0x00,0xFF,0x4A,0x4A,0x23,0x23,0x23,0x15,0x15,0x06,0x15,0x15,0x2C,
  0x23,0x7B,0x7B,0x00,0x4A,0x99,0xFF,0xFF,0xFF,0x4A,0x4A,0x4A,0x00,0x00,0x00,
  0x15,0x15,0x2C,0x15,0x4A,0x4A,0x00,0x23,0xB7,0x4A,0x4A,0x99,0x00,0x00,0x00,
  0x00,0x00,0x00,0x23,0x23,0x0A,0x15,0x4A,0x4A,0x15,0x4A,0x99,0x23,0x7B,0x7B,
  0x4A,0x4A,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x23,0x23,0x49,0x15,0x4A,0x99,
  0x15,0x4A,0x99,0x23,0x23,0x49,0x00,0x00,0x00,0x00,0x00,0x00,0x4A,0x4A,0x15,
  0x23,0x7B,0x7B,0x15,0x4A,0x99,0x15,0x4A,0x4A,0x23,0x23,0x0A,0x00,0x00,0x00,
  0xFF,0xFF,0x4A,0x4A,0x4A,0x99,0x00,0x23,0xB7,0x15,0x4A,0x4A,0x15,0x15,0x2C,
  0x00,0x00,0x00,0x4A,0x00,0x4A,0x00,0x00,0xFF,0x00,0x4A,0x99,0x23,0x7B,0x7B,
  0x15,0x15,0x2C,0x15,0x15,0x06,0x23,0x00,0x23,0xFF,0x00,0xFF,0x00,0xFF,0x4A,
  0x00,0x4A,0x99,0x23,0x23,0x49,0x15,0x15,0x06,0x15,0x00,0x15,0x7B,0x00,0x7B,
  0xFF,0x4A,0xFF,0x00,0x00,0xFF,0x4A,0x4A,0x99,0x23,0x23,0x0A,0x15,0x00,0x15,
  0x4A,0x00,0x4A,0xFF,0x23,0xFF,0x4A,0x4A,0xFF,0xFF,0xFF,0x4A,0x4A,0x4A,0x15,
  0x00,0x00,0x00,0x4A,0x00,0x4A,0x98,0x15,0x98,0x7B,0x23,0xFF,0x00,0x00,0xFF,
  0x00,0x00,0x00,0x00,0x00,0x00,0x23,0x00,0x23,0x98,0x15,0x98,0x98,0x15,0xFF,
  0x23,0x23,0xFF,0x00,0x00,0x4A,0x00,0x00,0x00,0x00,0x00,0x00,0x7B,0x00,0x7B,
  0x98,0x15,0xFF,0x4A,0x15,0xFF,0x00,0x00,0x7B,0x00,0x00,0x00,0x00,0x00,0x00,
  0x4A,0x00,0x4A,0xFF,0x23,0xFF,0x4A,0x15,0xFF,0x15,0x15,0x98,0x00,0x00,0x23,
  0x00,0x00,0x00,0xFF,0x00,0xFF,0xFF,0x00,0xFF,0x7B,0x23,0xFF,0x15,0x15,0x98,
  0x00,0x00,0x4A,0x00,0x00,0x00,0x4A,0x4A,0x4A,0xFF,0x00,0xFF,0xFF,0x4A,0xFF,
  0x23,0x23,0xFF,0x00,0x00,0x4A,0x00,0x00,0x15,0x23,0x23,0x23,0xFF,0x4A,0x4A,
  0xFF,0xFF,0xFF,0x4A,0x4A,0xFF,0x00,0x00,0x7B,0x00,0x00,0x15,0x15,0x15,0x15,
  0x7B,0x23,0x23,0xFF,0x4A,0x15,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0x23,
  0x15,0x15,0x15,0x4A,0x15,0x15,0xFF,0x7B,0x49,0x4A,0x4A,0x99,0x00,0x00,0xFF,
  0x00,0x00,0x4A,0x00,0x00,0x00,0x4A,0x15,0x15,0x98,0x4A,0x2C,0x7B,0x23,0x49,
  0x4A,0x4A,0x99,0x00,0x00,0x00,0x00,0x00,0x00,0x23,0x23,0x23,0x98,0x4A,0x2C,
  0x98,0x4A,0x6E,0x7B,0x7B,0x7B,0x4A,0x4A,0x15,0x00,0x00,0x00,0x00,0x00,0x00,
  0x7B,0x23,0x23,0x98,0x4A,0x6E,0x98,0x4A,0x4A,0x23,0x23,0x49,0x00,0x00,0x00,
  0x00,0x00,0x00,0x4A,0x4A,0x4A,0xFF,0x7B,0x49,0x98,0x4A,0x4A,0x4A,0x4A,0x4A,
  0x23,0x23,0x0A,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x4A,0x4A,0x7B,0x23,0x49,
  0x4A,0x4A,0x4A,0x15,0x15,0x2C,0x00,0x00,0x00,0x15,0x4A,0x4A,0xFF,0x00,0x00,
  0xFF,0x4A,0x15,0x7B,0x7B,0x7B,0x15,0x15,0x2C,0x15,0x15,0x06,0x0A,0x23,0x23,
  0x99,0x4A,0x4A,0xFF,0xFF,0x4A,0x4A,0x4A,0x99,0x23,0x23,0x49,0x15,0x15,0x06,
  0x06,0x15,0x15,0x49,0x23,0x23,0xFF,0x4A,0x15,0x00,0x00,0xFF,0x4A,0x4A,0x99,
  0x23,0x23,0x0A,0x06,0x15,0x15,0x2C,0x15,0x15,0xB7,0x7B,0x49,0xFF,0x4A,0x99,
  0xFF,0xFF,0x4A,0x4A,0x4A,0x15,0x00,0x00,0x00,0x2C,0x15,0x15,0x6E,0x4A,0x2C,
  0xFF,0x23,0x49,0x99,0x4A,0x99,0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0x23,0x23,
  0x6E,0x4A,0x2C,0xC8,0x4A,0x6E,0xB7,0x7B,0x7B,0x15,0x4A,0x15,0x00,0x00,0x00,
  0x00,0x00,0x00,0x49,0x23,0x23,0xC8,0x4A,0x6E,0xC8,0x4A,0x4A,0x49,0x23,0x49,
  0x00,0x00,0x00,0x00,0x00,0x00,0x15,0x4A,0x4A,0xB7,0x7B,0x49,0xC8,0x4A,0x4A,
  0x6E,0x4A,0x4A,0x0A,0x23,0x0A,0x00,0x00,0x00,0x4A,0xFF,0xFF,0x99,0x4A,0x4A,
  0xFF,0x23,0x49,0x6E,0x4A,0x4A,0x2C,0x15,0x2C,0x00,0x00,0x00,0x4A,0x4A,0x4A,
  0xFF,0x00,0x00,0xFF,0x4A,0x15,0xB7,0x7B,0x7B,0x2C,0x15,0x2C,0x06,0x15,0x06,
  0x23,0x23,0x23,0x4A,0x4A,0xFF,0xFF,0xFF,0x4A,0xFF,0x4A,0x99,0x49,0x23,0x49,
  0x06,0x15,0x06,0x15,0x15,0x15,0x23,0x23,0x7B,0x00,0x00,0xFF,0xFF,0x00,0xFF,
  0x99,0x4A,0x99,0x0A,0x23,0x0A,0x15,0x15,0x15,0x15,0x15,0x4A,0x23,0x23,0xFF,
  0x00,0x00,0xFF,0x4A,0xFF,0x4A,0x15,0x4A,0x15,0x00,0x00,0x00,0x15,0x15,0x4A,
  0x15,0x15,0x98,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,
  0x23,0x23,0x23,0x15,0x15,0x98,0x15,0x15,0xFF,0x00,0x00,0xFF,0x00,0x00,0x4A,
  0x00,0x00,0x00,0x00,0x00,0x00,0x23,0x23,0x7B,0x15,0x15,0xFF,0x00,0x00,0xFF,
  0x00,0x00,0x7B,0x00,0x00,0x00,0x00,0x00,0x00,0x4A,0x4A,0x4A,0x23,0x23,0xFF,
  0x00,0x00,0xFF,0x00,0x00,0x98,0x00,0x00,0x23,0x00,0x00,0x00,0xFF,0xFF,0xFF,
  0x4A,0x4A,0xFF,0x00,0x00,0xFF,0x00,0x00,0x98,0x00,0x00,0x4A,0x00,0x00,0x00,
  0x15,0x4A,0x15,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0x4A,
  0x00,0x00,0x15,0x0A,0x23,0x0A,0x99,0x4A,0x99,0x00,0x00,0xFF,0x00,0x00,0xFF,
  0x00,0x00,0x7B,0x00,0x00,0x15,0x06,0x15,0x06,0x49,0x23,0x49,0x99,0x4A,0x99,
  0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0x23,0x06,0x15,0x06,0x2C,0x15,0x2C,
  0x7B,0x7B,0x7B,0x99,0x4A,0x99,0x00,0x00,0xFF,0x00,0x00,0x4A,0x00,0x00,0x00,
  0x2C,0x15,0x2C,0x4A,0x4A,0x4A,0xB7,0x23,0xB7,0x99,0x4A,0x99,0x00,0x00,0x00,
  0x00,0x00,0x00,0x0A,0x23,0x0A,0x4A,0x4A,0x4A,0x99,0x4A,0x99,0x7B,0x7B,0x7B,
  0x15,0x4A,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x49,0x23,0x49,0x99,0x4A,0x99,
  0x99,0x4A,0x99,0x49,0x23,0x49,0x00,0x00,0x00,0x00,0x00,0x00,0x15,0x4A,0x15,
  0x7B,0x7B,0x7B,0x99,0x4A,0x99,0x4A,0x4A,0x4A,0x0A,0x23,0x0A,0x00,0x00,0x00,
  0x4A,0xFF,0x4A,0x99,0x4A,0x99,0xB7,0x23,0xB7,0x4A,0x4A,0x4A,0x2C,0x15,0x2C,
  0x00,0x00,0x00,0x15,0x4A,0x15,0xFF,0x00,0xFF,0x99,0x4A,0x99,0x7B,0x7B,0x7B,
  0x2C,0x15,0x2C,0x06,0x15,0x06,0x0A,0x23,0x0A,0x99,0x4A,0x99,0x4A,0xFF,0x4A,
  0x99,0x4A,0x99,0x49,0x23,0x49,0x06,0x15,0x06,0x06,0x15,0x06,0x49,0x23,0x49,
  0x99,0x4A,0xFF,0xFF,0x00,0xFF,0x99,0x4A,0x99,0x0A,0x23,0x0A,0x06,0x15,0x06,
  0x2C,0x15,0x2C,0x7B,0x7B,0xB7,0x15,0x4A,0xFF,0x4A,0xFF,0x4A,0x15,0x4A,0x15,
  0x00,0x00,0x00,0x2C,0x15,0x2C,0x4A,0x4A,0x6E,0x49,0x23,0xFF,0x15,0x4A,0x99,
  0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0x23,0x0A,0x4A,0x4A,0x6E,0x4A,0x4A,0xC8,
  0x23,0x7B,0xB7,0x15,0x4A,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x49,0x23,0x49,
  0x4A,0x4A,0xC8,0x4A,0x4A,0xC8,0x0A,0x23,0x49,0x00,0x00,0x00,0x00,0x00,0x00,
  0x15,0x4A,0x15,0x7B,0x7B,0xB7,0x4A,0x4A,0xC8,0x15,0x4A,0x6E,0x0A,0x23,0x0A,
  0x00,0x00,0x00,0x4A,0xFF,0x4A,0x99,0x4A,0x99,0x49,0x23,0xFF,0x15,0x4A,0x6E,
  0x06,0x15,0x2C,0x00,0x00,0x00,0x15,0x4A,0x15,0xFF,0x00,0xFF,0x99,0x4A,0xFF,
  0x23,0x7B,0xB7,0x06,0x15,0x2C,0x06,0x15,0x06,0x0A,0x23,0x0A,0x99,0x4A,0x99,
  0x4A,0xFF,0xFF,0x15,0x4A,0xFF,0x0A,0x23,0x49,0x06,0x15,0x06,0x06,0x15,0x06,
  0x49,0x23,0x49,0xFF,0x00,0xFF,0x00,0x00,0xFF,0x15,0x4A,0x99,0x0A,0x23,0x0A,
  0x06,0x15,0x06,0x2C,0x15,0x2C,0xB7,0x23,0xB7,0xFF,0x00,0xFF,0x4A,0xFF,0x4A,
  0x15,0x4A,0x15,0x00,0x00,0x00,0x2C,0x15,0x2C,0x6E,0x15,0x6E,0xFF,0x00,0xFF,
  0x99,0x4A,0x99,0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0x23,0x0A,0x6E,0x15,0x6E,
  0xC8,0x15,0xC8,0xB7,0x23,0xB7,0x15,0x4A,0x15,0x00,0x00,0x00,0x00,0x00,0x00,
  0x49,0x23,0x49,0xC8,0x15,0xC8,0xC8,0x15,0xC8,0x49,0x23,0x49,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x4A,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0x98,0x00,
  0x00,0x23,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,
  0x00,0x98,0x00,0x00,0x4A,0x00,0x00,0x00,0x00,0x15,0x4A,0x15,0x00,0xFF,0x00,
  0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0x4A,0x00,0x00,0x15,0x00,0x0A,0x23,0x0A,
  0x99,0x4A,0x99,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0x7B,0x00,0x00,0x15,0x00,
  0x06,0x15,0x06,0x49,0x23,0x49,0xFF,0x00,0xFF,0x00,0xFF,0x00,0x00,0xFF,0x00,
  0x00,0x23,0x00,0x06,0x15,0x06,0x2C,0x15,0x2C,0xB7,0x23,0xB7,0xFF,0x00,0xFF,
  0x00,0xFF,0x00,0x00,0x4A,0x00,0x00,0x00,0x00,0x2C,0x15,0x2C,0x6E,0x15,0x6E,
  0xFF,0x00,0xFF,0x99,0x4A,0x99,0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0x23,0x0A,
  0x6E,0x15,0x6E,0xC8,0x15,0xC8,0xB7,0x23,0xB7,0x15,0x4A,0x15,0x00,0x00,0x00,
  0x00,0x00,0x00,0x49,0x23,0x49,0xC8,0x15,0xC8,0xC8,0x15,0xC8,0x49,0x23,0x49,
  0x00,0x00,0x00,0x00,0x00,0x00,0x4A,0x4A,0x15,0x49,0x7B,0x7B,0x6E,0x4A,0x6E,
  0x6E,0x4A,0x2C,0x23,0x23,0x23,0x00,0x00,0x00,0xFF,0xFF,0x4A,0x4A,0x4A,0x99,
  0x49,0x23,0x49,0x6E,0x4A,0x2C,0x4A,0x15,0x15,0x00,0x00,0x00,0x15,0x4A,0x15,
  0x00,0x00,0xFF,0x15,0x4A,0x99,0xB7,0x7B,0x49,0x4A,0x15,0x15,0x15,0x15,0x15,
  0x0A,0x23,0x0A,0x99,0x4A,0x99,0x4A,0xFF,0x4A,0x99,0x4A,0x15,0x7B,0x23,0x23,
  0x15,0x15,0x15,0x06,0x15,0x06,0x49,0x23,0x49,0xFF,0x00,0xFF,0xFF,0x00,0x00,
  0xFF,0x4A,0x4A,0x23,0x23,0x23,0x06,0x15,0x06,0x2C,0x15,0x2C,0xB7,0x23,0xB7,
  0xFF,0x00,0xFF,0xFF,0xFF,0xFF,0x4A,0x4A,0x4A,0x00,0x00,0x00,0x2C,0x15,0x2C,
  0x6E,0x15,0x6E,0xFF,0x00,0xFF,0x99,0x4A,0x99,0x00,0x00,0x00,0x00,0x00,0x00,
  0x0A,0x23,0x0A,0x6E,0x15,0x6E,0xC8,0x15,0xC8,0xB7,0x23,0xB7,0x15,0x4A,0x15,
  0x00,0x00,0x00,0x00,0x00,0x00,0x49,0x23,0x49,0xC8,0x15,0xC8,0xC8,0x15,0xC8,
  0x49,0x23,0x49,0x00,0x00,0x00,0x00,0x00,0x00,0x4A,0x4A,0x15,0x23,0x7B,0x7B,
  0x15,0x4A,0x99,0x15,0x4A,0x4A,0x23,0x23,0x0A,0x00,0x00,0x00,0xFF,0xFF,0x4A,
  0x4A,0x4A,0x99,0x00,0x23,0xB7,0x15,0x4A,0x4A,0x15,0x15,0x2C,0x00,0x00,0x00,
  0x15,0x4A,0x15,0x00,0x00,0xFF,0x00,0x4A,0x99,0x23,0x7B,0x7B,0x15,0x15,0x2C,
  0x15,0x15,0x06,0x0A,0x23,0x0A,0x99,0x4A,0x99,0x00,0xFF,0x4A,0x00,0x4A,0x99,
  0x23,0x23,0x49,0x15,0x15,0x06,0x06,0x15,0x06,0x49,0x23,0x49,0xFF,0x00,0xFF,
  0x00,0x00,0xFF,0x4A,0x4A,0x99,0x23,0x23,0x0A,0x06,0x15,0x06,0x2C,0x15,0x2C,
  0xB7,0x23,0xB7,0xFF,0x00,0xFF,0xFF,0xFF,0x4A,0x4A,0x4A,0x15,0x00,0x00,0x00,
  0x2C,0x15,0x2C,0x6E,0x15,0x6E,0xFF,0x00,0xFF,0x99,0x4A,0x99,0x00,0x00,0x00,
  0x00,0x00,0x00,0x0A,0x23,0x0A,0x6E,0x15,0x6E,0xC8,0x15,0xC8,0xB7,0x23,0xB7,
  0x15,0x4A,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x49,0x23,0x49,0xC8,0x15,0xC8,
  0xC8,0x15,0xC8,0x49,0x23,0x49,0x00,0x00,0x00,0x00,0x00,0x00,0x4A,0x4A,0x4A,
  0xFF,0x7B,0x49,0x98,0x4A,0x4A,0x4A,0x4A,0x4A,0x23,0x23,0x0A,0x00,0x00,0x00,
  0xFF,0xFF,0xFF,0xFF,0x4A,0x4A,0x7B,0x23,0x49,0x4A,0x4A,0x4A,0x15,0x15,0x2C,
  0x00,0x00,0x00,0x15,0x4A,0x15,0xFF,0x00,0x00,0xFF,0x4A,0x15,0x7B,0x7B,0x7B,
  0x15,0x15,0x2C,0x15,0x15,0x06,0x0A,0x23,0x0A,0x99,0x4A,0x99,0xFF,0xFF,0x4A,
  0x4A,0x4A,0x99,0x23,0x23,0x49,0x15,0x15,0x06,0x06,0x15,0x06,0x49,0x23,0x49,
  0xFF,0x00,0xFF,0x00,0x00,0xFF,0x4A,0x4A,0x99,0x23,0x23,0x0A,0x06,0x15,0x06,
  0x2C,0x15,0x2C,0xB7,0x23,0xB7,0xFF,0x00,0xFF,0xFF,0xFF,0x4A,0x4A,0x4A,0x15,
  0x00,0x00,0x00,0x2C,0x15,0x2C,0x6E,0x15,0x6E,0xFF,0x00,0xFF,0x99,0x4A,0x99,
  0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0x23,0x0A,0x6E,0x15,0x6E,0xC8,0x15,0xC8,
  0xB7,0x23,0xB7,0x15,0x4A,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x49,0x23,0x49,
  0xC8,0x15,0xC8,0xC8,0x15,0xC8,0x49,0x23,0x49,0x00,0x00,0x00,0x00,0x00,0x00,
  0x15,0x4A,0x15,0x7B,0x7B,0x7B,0x99,0x4A,0x99,0x4A,0x4A,0x4A,0x0A,0x23,0x0A,
  0x00,0x00,0x00,0x4A,0xFF,0x4A,0x99,0x4A,0x99,0xB7,0x23,0xB7,0x4A,0x4A,0x4A,
  0x2C,0x15,0x2C,0x00,0x00,0x00,0x15,0x4A,0x15,0xFF,0x00,0xFF,0x99,0x4A,0x99,
  0x7B,0x7B,0x7B,0x2C,0x15,0x2C,0x06,0x15,0x06,0x0A,0x23,0x0A,0x99,0x4A,0x99,
  0x4A,0xFF,0x4A,0x99,0x4A,0x99,0x49,0x23,0x49,0x06,0x15,0x06,0x06,0x15,0x06,
  0x49,0x23,0x49,0xFF,0x00,0xFF,0xFF,0x00,0xFF,0x99,0x4A,0x99,0x0A,0x23,0x0A,
  0x06,0x15,0x06,0x2C,0x15,0x2C,0xB7,0x23,0xB7,0xFF,0x00,0xFF,0x4A,0xFF,0x4A,
  0x15,0x4A,0x15,0x00,0x00,0x00,0x2C,0x15,0x2C,0x6E,0x15,0x6E,0xFF,0x00,0xFF,
  0x99,0x4A,0x99,0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0x23,0x0A,0x6E,0x15,0x6E,
  0xC8,0x15,0xC8,0xB7,0x23,0xB7,0x15,0x4A,0x15,0x00,0x00,0x00,0x00,0x00,0x00,
  0x49,0x23,0x49,0xC8,0x15,0xC8,0xC8,0x15,0xC8,0x49,0x23,0x49,0x00,0x00,0x00,
  0x00,0x00,0x00,0x15,0x4A,0x15,0x7B,0x7B,0xB7,0x4A,0x4A,0xC8,0x15,0x4A,0x6E,
  0x0A,0x23,0x0A,0x00,0x00,0x00,0x4A,0xFF,0x4A,0x99,0x4A,0x99,0x49,0x23,0xFF,
  0x15,0x4A,0x6E,0x06,0x15,0x2C,0x00,0x00,0x00,0x00,0x4A,0x00,0xFF,0x00,0xFF,
  0x99,0x4A,0xFF,0x23,0x7B,0xB7,0x06,0x15,0x2C,0x06,0x15,0x06,0x00,0x23,0x00,
  0x00,0xFF,0x00,0x4A,0xFF,0xFF,0x15,0x4A,0xFF,0x0A,0x23,0x49,0x06,0x15,0x06,
  0x00,0x15,0x00,0x00,0x7B,0x00,0x00,0xFF,0x00,0x00,0x00,0xFF,0x15,0x4A,0x99,
  0x0A,0x23,0x0A,0x00,0x15,0x00,0x00,0x4A,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,
  0x4A,0xFF,0x4A,0x15,0x4A,0x15,0x00,0x00,0x00,0x00,0x4A,0x00,0x00,0x98,0x00,
  0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x23,0x00,
  0x00,0x98,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0x4A,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x7B,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0x7B,0x00,
  0x00,0x00,0x00 },
odo24[] = { // Special 12/24 hour odometer symbol (different width from others)
  0x00,0x00,0x00,0x00,0x00,0x00,0x4A,0x00,0x4A,0x4A,0x00,0xFF,0x00,0x7B,0x7B,
  0x00,0x98,0x00,0x4A,0x4A,0x00,0x4A,0x00,0x4A,0x15,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xFF,0xFF,0x00,0xFF,0x00,0x4A,0xFF,
  0x00,0xFF,0x00,0x7B,0x7B,0x00,0x4A,0x00,0x4A,0x15,0x00,0x15,0x00,0x15,0x15,
  0x00,0x00,0x00,0x00,0x00,0x4A,0x4A,0x00,0x4A,0x00,0x00,0xFF,0x00,0x00,0xFF,
  0x00,0xFF,0x00,0x4A,0x4A,0x00,0x7B,0x00,0x7B,0x23,0x00,0x15,0x00,0x15,0x15,
  0x00,0x00,0x00,0x00,0x00,0x23,0x23,0x00,0x23,0x00,0x4A,0xFF,0x00,0xFF,0x00,
  0x00,0xFF,0x00,0xFF,0x00,0x00,0xFF,0x00,0xFF,0x4A,0x00,0x23,0x00,0x23,0x23,
  0x00,0x00,0x00,0x00,0x00,0x15,0x15,0x00,0x15,0x00,0x23,0x7B,0x00,0x7B,0x00,
  0x4A,0x4A,0x00,0xFF,0x4A,0x00,0xFF,0x00,0xFF,0xFF,0x00,0x4A,0x00,0x4A,0x4A,
  0x00,0x00,0x00,0x00,0x00,0x15,0x15,0x00,0x15,0x00,0x15,0x4A,0x00,0x4A,0x00,
  0x7B,0x7B,0x00,0xFF,0x23,0xFF,0x4A,0x00,0x4A,0xFF,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x15,0x4A,0x00,0x4A,0x00,
  0x4A,0x4A,0x00,0x98,0x15,0x7B,0x7B,0x00,0x7B,0x7B,0x4A,0x4A,0x00,0x00,0x4A,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x23,0x23,0x00,0x23,0x00,
  0x4A,0x4A,0x00,0x98,0x15,0x98,0x98,0x00,0x98,0x4A,0x7B,0x23,0x00,0x23,0x7B,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x23,0x7B,0x00,0x7B,0x00,0x98,0x98,0x00,0x98,0x4A,0x4A,0x4A,0x00,0x4A,0x4A,
  0x23,0x23,0x00,0x00,0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x4A,0x4A,0x00,0x4A,0x00,0x7B,0x7B,0x00,0xFF,0x23,0x4A,0x4A,0x00,0x4A,0x4A,
  0x4A,0x15,0x00,0x15,0x4A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0xFF,0xFF,0x00,0xFF,0x00,0x4A,0xFF,0x00,0xFF,0x00,0x7B,0x7B,0x00,0x7B,0x7B,
  0x4A,0x15,0x00,0x15,0x4A,0x15,0x15,0x00,0x00,0x15,0x00,0x00,0x00,0x00,0x00,
  0x00,0x4A,0x00,0x4A,0x4A,0x00,0xFF,0x00,0xFF,0x00,0x4A,0x4A,0x00,0xFF,0x4A,
  0x7B,0x23,0x00,0x23,0x7B,0x15,0x15,0x00,0x00,0x15,0x00,0x00,0x00,0x00,0x00,
  0x00,0x23,0x00,0x23,0x23,0x00,0xFF,0x00,0x4A,0xFF,0xFF,0x00,0x00,0xFF,0xFF,
  0xFF,0x4A,0x00,0x4A,0xFF,0x23,0x23,0x00,0x00,0x23,0x00,0x00,0x00,0x00,0x00,
  0x00,0x15,0x00,0x15,0x15,0x00,0x7B,0x00,0x23,0x7B,0x00,0xFF,0x00,0x4A,0x4A,
  0xFF,0xFF,0x00,0x00,0xFF,0x4A,0x4A,0x00,0x00,0x4A,0x00,0x00,0x00,0x00,0x00,
  0x00,0x15,0x00,0x15,0x15,0x00,0x4A,0x00,0x15,0x4A,0x00,0xFF,0x00,0x7B,0x7B,
  0x00,0xFF,0x00,0xFF,0x4A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x4A,0x00,0x15,0x4A,0x00,0x98,0x00,0x4A,0x4A,
  0x00,0xFF,0x00,0x7B,0x7B,0x00,0x4A,0x00,0x4A,0x4A,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x23,0x00,0x23,0x23,0x00,0x98,0x00,0x4A,0x4A,
  0x00,0xFF,0x00,0x98,0x98,0x00,0x7B,0x00,0x7B,0x23,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7B,0x00,0x23,0x7B,
  0x00,0xFF,0x00,0x98,0x98,0x00,0x98,0x00,0x4A,0x4A,0x00,0x23,0x00,0x23,0x23,
  0x00,0x00,0x00,0x00,0x00 },
symbols[] = { // Various symbols (Y/M/D etc.)
  0xFF,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0xFF,0xFF,
  0xFF,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0x00,0x00,0x00,0xFF,0xFF,
  0xFF,0x00,0xFF,0xFF,0x00,0x00,0x00,0xFF,0x00,0xFF,0x00,0x00,0xFF,0xFF,0x00,
  0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0xFF,
  0xFF,0xFF,0x00,0xFF,0x00,0x00,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0xFF,
  0x00,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0x00,0x00,0xFF,0x00,0xFF,0x00,0x00,
  0xFF,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0xFF,0x00,
  0xFF,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0xFF,0x00 },
//                   Y   Y . M   M . D   D   H   H : M   M : 24
  xOffset[]     = {  0,  4, 10, 14, 20, 24, 30, 34, 40, 44, 48 },
  xScroll[]     = {  0,  1,  8, 11, 18, 21, 28, 31, 38, 41, 45 },
  limit[]       = {  9,  9,  1,  9,  3,  9,  2,  9,  5,  9,  1 },
  daysInMonth[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

#include <RTClib.h>
#include <Watch.h>
#include "Watch_common.h"

static uint8_t
  dNum    = 0, // Current digit # being edited
  symFade = 0; // Frame counter for symbol fade-out
static int
  destX   = 0; // Final position of date/time display

void flip() ;

void mode_set(uint8_t action) {

  if(action != ACTION_NONE) {

    if(action >= ACTION_HOLD_BOTH) {

      // Just arrived -- initialize time-setting mode.
      // Load up initial clock state
      dNum = 0;
      curX = destX = 0;
      symFade = sizeof(fade);
      DateTime now = RTC.now();
      loadDigits(now.year() - 2000, DIGIT_YEAR0);
      loadDigits(now.month()      , DIGIT_MON0);
      loadDigits(now.day()        , DIGIT_DAY0);
      loadDigits(now.hour()       , DIGIT_HR0);
      loadDigits(now.minute()     , DIGIT_MIN0);

      // A relatively large amount of time will be spent in this
      // mode, so the LED matrix is set to the most multiplexed
      // mode (1 LED at a time) to conserve power.  This allows
      // 2 color bits max.
      // Reconfigure display if needed
      if((watch.getDepth() != 2) || (watch.getPlex() != LED_PLEX_1))
        fps = watch.setDisplayMode(2, LED_PLEX_1, true);
    }
    // Reset sleep timeout on ANY button action.
    watch.setTimeout(fps * 8);

    if(action == ACTION_TAP_RIGHT) {

      // Increase digit value, wrap around as appropriate
      if(dNum == DIGIT_24) {
        for(uint8_t i=1; i<7; i++) {
          drawTime();
          blit(odo24, 35, 16, i * 5, 0, 3, 0, 5, 8, 255);
          watch.swapBuffers();
        }
        h24 = !h24;
      } else {
        flip();
      }

    } else if(action == ACTION_TAP_LEFT) {

      // Advance to next digit position
      // TBD: When advancing past 12/24, might instead make this go
      // back to time display mode instead of the year setting.
      if(++dNum > DIGIT_24) dNum = DIGIT_YEAR0;
      destX = -pgm_read_byte(&xScroll[dNum]);
  
      // When switching to first digit of new section,
      // fade out corresponding overlay symbol
      if((dNum==DIGIT_YEAR0) || (dNum==DIGIT_MON0) || (dNum==DIGIT_DAY0) ||
         (dNum==DIGIT_HR0  ) || (dNum==DIGIT_MIN0)) {
         symFade = sizeof(fade) + 5; // Run a few frames at full brightness
         if(dNum == DIGIT_YEAR0) symFade += 48; // Allow extra scrolling time
       }

    }
  }

  drawTime();
  if(curX != destX) curX += (destX > curX) ? 1 : -1; // Update scroll position
  if(symFade > 0) symFade--; // Update symbol fade counter
}

void flip() {
  uint8_t i, lower, upper, srcY, destX, m, d;

  // Most digits have a simple upper limit where they roll over to zero:
  upper = pgm_read_byte(&limit[dNum]);
  // But a few have special behaviors in special cases...

  // For example, month and day counts start at 1; there is no "month zero."
  // But this is only a concern when the month or day is less than 10.
  if(((dNum == DIGIT_MON1) || (dNum == DIGIT_DAY1)) && (digit[dNum - 1] == 0)) {
    lower = 1;
    // If rolling over from 9 to 1, use special animation
    // sequence, otherwise use the standard odometer digits:
    srcY  = (digit[dNum] == upper) ? 120 : digit[dNum] * 8;
  } else {
    lower = 0;
    // In other situations, the upper limit before rollover varies.
    // e.g. if month >= 10, then the upper limit for the second digit
    // becomes 2 (rather than 9):
    if(dNum == DIGIT_MON1) {
      if(digit[DIGIT_MON0] == 1) upper = 2;
    } else if(dNum == DIGIT_DAY1) {
      // Cap most months at 30 or 31 days as appropriate
      if(digit[DIGIT_DAY0] == 3) {
        uint8_t m = digit[DIGIT_MON0] * 10 + digit[DIGIT_MON1];
        upper = pgm_read_byte(&daysInMonth[m - 1]) % 10;
      // Finally, the dreaded leap year...
      } else if((digit[DIGIT_DAY0] == 2) && (digit[DIGIT_MON0] == 0) &&
                (digit[DIGIT_MON1] == 1)) {
        uint8_t y = digit[DIGIT_YEAR0] * 10 + digit[DIGIT_YEAR1];
        if((y == 0) || (y & 3)) upper = 8; // non-leap year
      }
    } else if(dNum == DIGIT_HR1) {
      if(digit[DIGIT_HR0] == 2) upper = 3;
    }

    // In 30-day months, second digit can't roll over to anything
    if(upper == lower) return;

    switch(upper) { // Certain rollovers have special animations
     case 1:  srcY =   80; break;     // 1->0 animation
     case 2:  srcY =   88; break;     // 2->0
     case 3:  srcY =   96; break;     // 3->0
     case 5:  srcY =  104; break;     // 5->0
     case 8:  srcY =  112; break;     // 8->0
     default: srcY = digit[dNum] * 8; // Standard 0-9 animation
    }
  }

  destX = curX + pgm_read_byte(&xOffset[dNum]);

  // Animate rolling digit.  Static time is drawn
  // first, then rolling digit is overwritten.
  for(i=3; i<21; i += 3) {
    drawTime();
    blit(odoDigits, 21, 128, i, srcY, destX, 0, 3, 8, 255);
    watch.swapBuffers();
  }

  // Increment digit value w/wraparound
  if(++digit[dNum] > upper) digit[dNum] = lower;

  // After incrementing digit, subsequent digits need to also be
  // constrained for validity...for example, when changing the
  // first digit of the month, the second digit needs to be limited
  // to reality (e.g. 09 jumps to 10, not 19).  Likewise w/day.
  switch(dNum) {
   case DIGIT_MON0:
    if((digit[DIGIT_MON0] == 1) && (digit[DIGIT_MON1] > 2))
      digit[DIGIT_MON1] = 0;
    // Lack of break is intentional...all subsequent constraints apply.
   case DIGIT_MON1:
    m = digit[DIGIT_MON0] * 10 + digit[DIGIT_MON1];
    if(m < 1) loadDigits(1, DIGIT_MON0);
   case DIGIT_DAY0:
    m     = digit[DIGIT_MON0] * 10 + digit[DIGIT_MON1];
    d     = digit[DIGIT_DAY0] * 10 + digit[DIGIT_DAY1];
    upper = pgm_read_byte(&daysInMonth[m - 1]);
    if(m == 2) { // is February
      uint8_t y = digit[DIGIT_YEAR0] * 10 + digit[DIGIT_YEAR1];
      if((y > 0) && !(y & 3)) upper = 29; // is leap year
    }
    if(d > upper)  loadDigits(upper, DIGIT_DAY0);
    else if(d < 1) loadDigits(1, DIGIT_DAY0);
   case DIGIT_HR0:
   case DIGIT_HR1:
    if((digit[DIGIT_HR0] * 10 + digit[DIGIT_HR1]) > 23)
      loadDigits(23, DIGIT_HR0);
  }
}

static const uint8_t PROGMEM
  symX[]      = { 0, 5, 14, 9, 5, 19 }, // Starting column # in symbols bitmap
  symOffset[] = { 2, 0,  0, 0, 0,  0 }; // Add to X when drawing symbol

void drawTime() {
  uint8_t  i, brightness;
  uint16_t t;

  watch.fillScreen(0);

  brightness = ((t = watch.getTimeout()) < sizeof(fade)) ?
    ((255 * ((uint8_t)pgm_read_byte(&fade[t]) + 1)) >> 8) : 255;

  uint8_t b = (symFade < sizeof(fade)) ?
    ((brightness * ((uint8_t)pgm_read_byte(&fade[symFade]) + 1)) >> 8) :
    brightness;

  if(symFade) {
    blit(symbols, 24, 5, pgm_read_byte(&symX[dNum / 2]), 0,
      curX + pgm_read_byte(&xOffset[dNum]) + pgm_read_byte(&symOffset[dNum / 2]), 1, 5, 5, b);
  }
 
  for(i=DIGIT_YEAR0; i<=DIGIT_MIN1; i++) {
    // either skip or overwrite 'symfade' digits
    if(symFade && (i == dNum)) {
      i++;
      continue;
    }
    blit(odoDigits, 21, 128, 0, digit[i] * 8 + 1,
      curX + pgm_read_byte(&xOffset[i]), 1, 3, 5, brightness);
  }

  // draw 12/24
  blit(odo24, 35, 16, 0, h24 ? 8 : 0,
    curX + pgm_read_byte(&xOffset[10]), 0, 5, 8, brightness);

  // Add punctuation
  brightness >>= (8 - 2); // Change blit opacity to pixel value; 2 = depth
  watch.drawPixel(curX +  8, 3, brightness);
  watch.drawPixel(curX + 18, 3, brightness);
  watch.drawPixel(curX + 38, 2, brightness);
  watch.drawPixel(curX + 38, 4, brightness);

  // And underline current digit
  if(watch.getCursorBlink()) {
    watch.drawLine(curX + pgm_read_byte(&xOffset[dNum]), 7,
      curX + pgm_read_byte(&xOffset[dNum]) + ((dNum == DIGIT_24) ? 4 : 2),
      7, brightness >> 1);
  }
}

void set() {
  DateTime dt(
    digit[DIGIT_YEAR0 ] * 10 + digit[DIGIT_YEAR1] + 2000,
    digit[DIGIT_MON0  ] * 10 + digit[DIGIT_MON1 ],
    digit[DIGIT_DAY0  ] * 10 + digit[DIGIT_DAY1 ],
    digit[DIGIT_HR0   ] * 10 + digit[DIGIT_HR1  ],
    digit[DIGIT_MIN0  ] * 10 + digit[DIGIT_MIN1 ],
    0); // Seconds are always reset to 0 when exiting time set
  RTC.adjust(dt);
}

void loadDigits(int in, uint8_t idx) {
  digit[idx    ] = in / 10;
  digit[idx + 1] = in - (digit[idx] * 10);
}

